package com.itheima.core;

import com.itheima.domain.Configuration;
import com.itheima.domain.Mapper;
import com.itheima.utils.Executor;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.List;
import java.util.Map;

public class DefaultSqlSession implements SqlSession {
    private Configuration cfg;
    public DefaultSqlSession(Configuration cfg) {
        this.cfg = cfg;
    }

    // 查询所有信息 // user.findAll
    public <T> List<T> findAll(String mapperId) {
        List<T> list = null;
        try {
            // 加载驱动,创建连接,预编译sql,执行并返回结果集
            Map<String, Mapper> mappers = cfg.getMappers();
            Mapper mapper = mappers.get(mapperId);
            String sql = mapper.getSql();
            String resultType = mapper.getResultType();  // 返回的数据类型
            Executor executor = new Executor(cfg);
            list = executor.executeQuery(sql, resultType);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return list;
    }

    /**
     * 动态代理方式创建dao层的实现类对象
     * @param clazz  dao层接口的字节码文件
     * @return
     */
    public <E> E getMapper(Class clazz) {
        E proxy = (E) Proxy.newProxyInstance(
                clazz.getClassLoader(), // 类加载器
                new Class[]{clazz}, // 代理类对象需要实现的接口
                new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        if ("findAll".equals(method.getName())) {
                            // 类对象的字节码对象.
                            // 当前类所实现的接口的权限定名
                            String typeName = proxy.getClass().getGenericInterfaces()[0].getTypeName();
                            // 调用findAll方法
                            List list = findAll(typeName + "." + method.getName());
                            return list;
                        }
                        return null;
                    }
                }
        );
        return proxy;
    }


}
